package com.consul.config;

import com.ecwid.consul.v1.agent.model.NewService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration;
import org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author yinxing
 * @date 2022-08-15
 */
@Slf4j
@Component
public class ConsulRetryRegistry implements CommandLineRunner {
    private ConsulAutoRegistration consulAutoRegistration;
    private ConsulServiceRegistry consulServiceRegistry;
    private DiscoveryClient discoveryClient;

    public ConsulRetryRegistry(
            ConsulAutoRegistration consulAutoRegistration,
            ConsulServiceRegistry consulServiceRegistry,
            DiscoveryClient discoveryClient
    ) {
        this.consulAutoRegistration = consulAutoRegistration;
        this.consulServiceRegistry = consulServiceRegistry;
        this.discoveryClient = discoveryClient;
    }

    @Override
    public void run(String... args) throws Exception {
        final NewService service = this.consulAutoRegistration.getService();
        // 启动一个线程进行服务监测
        ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,new BasicThreadFactory.Builder().daemon(true).build());
        executorService.scheduleAtFixedRate(() -> {
            // 健康检查
            if (!checkStatus(service)) {
                try {
                    log.info("==============consul服务挂了，重新连接中=============");
                    this.consulServiceRegistry.register(this.consulAutoRegistration);
                }catch (Exception e) {
                    log.error(e.getMessage());
                }
            }
        }, 0, 10000, TimeUnit.MILLISECONDS);
    }

    private boolean checkStatus(NewService service) {
        // 检测标志
        boolean flag = false;
        try {
            // 获取所有服务实例
            List<ServiceInstance> instances = this.discoveryClient.getInstances(service.getName());
            for (ServiceInstance instance : instances) {
                // 判断是否为当前服务
                if (instance.getServiceId().equals(service.getName())) {
                    flag = true;
                    break;
                }
            }
        }catch (Exception e){
            log.error(e.getMessage());
        }
        return flag;
    }
}
